#include "ringbuffer.h"
#include <string.h>


typedef enum
{
    RINGBUFFER_NORMAL,
    RINGBUFFER_EMPTY,
    RINGBUFFER_FULL,
    RINGBUFFER_HALFFULL,
} RingBuffer_State;

static RingBuff_type_t RingBuff = {0};
static volatile uint8_t* m_lock = 0;

void get_lock(void)
{
    while(*m_lock == 1);
    *m_lock = 1;
}

void put_lock(void)
{
    while(*m_lock == 0);
    *m_lock = 0;
}

void RingBuffer_Init(void)
{
    RingBuff.Read_Index  = 0;
    RingBuff.Write_Index = 0;
    RingBuff.Buff_Size = RingBuffSize;
    RingBuff.Buff_Length = 0;
    memset(RingBuff.Buff_Ptr, 0, RingBuffSize);
}

static RingBuffer_State RingBuffer_Empty(void)
{
    RingBuffer_State status = RINGBUFFER_NORMAL;
    /*ringbuff is empty */
    if(RingBuff.Buff_Length == 0)
    {
        status = RINGBUFFER_EMPTY;
    }

    return status;
}

static RingBuffer_State RingBuffer_Full(void)
{
    RingBuffer_State status = RINGBUFFER_NORMAL;
    /*ringbuff is full */
    if(RingBuff.Buff_Length == RingBuff.Buff_Size-1)
    {
        status = RINGBUFFER_FULL;
    }
    return status;
}

uint8_t RingBuffer_Write_Byte(const uint8_t Byte)
{
    RingBuffer_State status = RINGBUFFER_NORMAL;
    /*get ringbuff status */
    status = RingBuffer_Full();

    if (status == RINGBUFFER_FULL)
    {
        return 0;
    }
    else
    {
        /*copy ptr data into ringbuff */
        get_lock();
        RingBuff.Buff_Ptr[RingBuff.Write_Index] = Byte;
        RingBuff.Write_Index = (RingBuff.Write_Index+1)%RingBuff.Buff_Size;
        RingBuff.Buff_Length++;
        put_lock();
        return 1;
    }
}

uint8_t RingBuffer_Read_Byte(uint8_t* Byte)
{
    RingBuffer_State status = RINGBUFFER_NORMAL;
    /*get ringbuff status */
    status = RingBuffer_Empty();
    if(status == RINGBUFFER_EMPTY)
    {
        return 0;
    }
    else
    {
        get_lock();
        *Byte = RingBuff.Buff_Ptr[RingBuff.Read_Index];
        RingBuff.Read_Index = (RingBuff.Read_Index+1)%RingBuff.Buff_Size;
        RingBuff.Buff_Length--;
        put_lock();
        return 1;
    }
}

uint8_t RingBuffer_Clear_Buffer(void)
{
    RingBuff.Buff_Length = 0;
    return 0;
}


